package com.prs.crm.dao.impl;

import java.io.Serializable;

import org.courser.dao.DaoSupportImpl;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.prs.crm.annotation.DomainRelation;
import com.prs.crm.annotation.DomainRelations;
import com.prs.crm.context.Constrains;
import com.prs.crm.context.ToolKits;
import com.prs.crm.dao.BaseDao;
import com.prs.crm.domain.BaseEntity;
import com.prs.crm.exception.InValidDeleteException;

/**
 * 基础Dao实现
 * @author courser.tijichen
 *
 * @param <T>
 */
public class BaseDaoImpl<T> extends DaoSupportImpl<T> implements BaseDao<T>{
	


	@Override
	public void save(T object)
	{
		
		super.save(object);
	}
	
	@Override
	public int updateSign(final java.io.Serializable[] ids,final int status)
	{
		final Class<T> cls = this.getEntityClass();
		return (Integer)getHibernateTemplate().execute(   
			      new HibernateCallback() {   
			        public Object doInHibernate(Session session) throws HibernateException {   
			        	Query query = session.createQuery("update "+cls.getSimpleName()+" set sign=? where id in ("+ToolKits.constructInSql((Integer[])ids)+")");
			        	query.setParameter(0, status);
			            return query.executeUpdate();
			        
			        }   
			      }   
			    );
	}
	
	@Override 
	public void remove(T entity)
	{
		try
		{
			DomainRelations relations = entity.getClass().getAnnotation(DomainRelations.class);
			if (relations!=null)
			{
				for (DomainRelation relation : relations.relations())
				{
					if (countRely(relation.rely(),relation.property(),entity)>0)
						throw new InValidDeleteException("有关联数据,无法删除");
				}
			}
			super.remove(entity);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new InValidDeleteException(e.getMessage());
		}
	}
	
	private int countRely(final String className,final String property,final T entity) throws Exception
	{
		final Class<?> domain =Class.forName(className);
		return (Integer)getHibernateTemplate().execute(   
			      new HibernateCallback() {   
			        public Object doInHibernate(Session session) throws HibernateException {   
			            Criteria crit =   
			              session.createCriteria(domain);
			            crit.add(Restrictions.eq(property,entity));
			            crit.setProjection(Projections.rowCount());
			            return crit.uniqueResult();
			        
			        }   
			      }   
			    );
	
	}
	/**
	 * 批量删除  
	 */
	public int batchRemove(Serializable[] ids)
	{
		if (ids!=null && ids.length>0)
		{
			int count=0;
			for (Serializable id :ids)
			{
				T entity = this.get(id);
				this.remove(entity);
				count++;
			}
			return count;
		}
		else
		{
			return 0;
		}
	}
	
	//批量草稿
	public int batchDraft(Serializable[] ids)
	{
		if (ids!=null && ids.length>0)
		{
			int count=0;
			for (Serializable id :ids)
			{
				T entity = this.get(id);
				((BaseEntity)entity).setSign(Constrains.SIGN_DRAFT);
				this.save(entity);
				count++;
			}
			return count;
		}
		else
		{
			return 0;
		}
	}
	
	//批量回收
	public int batchTrash(Serializable[] ids)
	{
		if (ids!=null && ids.length>0)
		{
			int count=0;
			for (Serializable id :ids)
			{
				T entity = this.get(id);
				((BaseEntity)entity).setSign(Constrains.SIGN_TRASH);
				this.save(entity);
				count++;
			}
			return count;
		}
		else
		{
			return 0;
		}
	}
	
	//批量回收
	public int batchSubmit(Serializable[] ids)
	{
		if (ids!=null && ids.length>0)
		{
			int count=0;
			for (Serializable id :ids)
			{
				T entity = this.get(id);
				((BaseEntity)entity).setSign(Constrains.SIGN_FORMAL);
				this.save(entity);
				count++;
			}
			return count;
		}
		else
		{
			return 0;
		}
	}
}
